home *** CD-ROM | disk | FTP | other *** search
- #include <stdarg.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <limits.h>
- #include <errno.h>
- #include "internal.h"
-
- #ifdef UNIX
- #define MAXIMUM_PATH PATH_MAX
- #else
- #define MAXIMUM_PATH 128
- #endif
-
- #define MISSING_MESSAGE "-???-"
- /*
- Print an error message in a popup
- Stubs to avoid linking the world
- */
- void xconf_error (const char *msg, ...)
- {
- va_list list;
- va_start (list,msg);
- vfprintf (stderr,msg,list);
- va_end (list);
- }
-
-
-
- /* #Specification: translation / principle
- The translation mecanism used by linuxconf is fairly
- different from other system in used. Most system use
- an external dictionary which can be translated without
- recompiling the source. Linuxconf use a similar setup
- except the dictionary is updated from the source.
-
- First msgscan is used to produce/update dictionnaries by
- scanning all source file. It looks for macros like
-
- #
- MSG_U(ID,"english message")
- #
-
- or already translated ones
-
- #
- MSG_B(ID,"english message","french message")
- #
-
- From that, it produce a dictionary.
-
- This disctionary is then compiled and produce one include
- file per dictionary and a resource message file which
- contain several dictionary.
-
- One program may very well used several
- dictionary and a dictionary may be compiled in many
- message resource file.
- */
-
-
- static const char *msgcomp_getmsg (
- TR_STRING *t,
- const char *lang)
- {
-
- const char *ret = NULL;
- while (*lang != '\0'){
- ret = t->getmsg(lang[0]);
- if (ret != NULL) break;
- lang++;
- }
- return ret;
- }
-
- static const char *msgcomp_getmsg (
- TR_STRING *t,
- TR_STRINGS *trans, // Alternative dictionary to use
- const char *lang,
- const char *sysname) // Use to print error message
- // If NULL, no error needed
- {
- const char *ret = NULL;
- TR_STRING *tt = trans->getitem(t->getid());
- if (tt != NULL) ret = msgcomp_getmsg (tt,lang);
- if (ret == NULL) ret = msgcomp_getmsg(t,lang);
- if (ret == NULL && sysname != NULL){
- fprintf (stderr,"Missing message %s, system %s\n"
- ,t->getid(),sysname);
- }
- return ret;
- }
-
- class TR_STRINGS_COMP{
- public:
- TR_STRINGS ref; // Reference dictionary
- TR_STRINGS trans; // Translation
- /*~PROTOBEG~ TR_STRING_COMP */
- /*~PROTOEND~ TR_STRING_COMP */
- };
-
- static int msgcomp_write (
- const char *outfile,
- TR_STRINGS_COMP trs[],
- char *sysnames[],
- int nbsys,
- char *lang) // Language to generate
- // Instead of being a letter, it is a string of
- // letter. The first one is the prefered one
- // the other are fallback if the first is missing
- {
- int ret = -1;
- FILE *fout = fopen (outfile,"wb");
- if (fout == NULL){
- fprintf (stderr,"Can't open file %s (%s)\n"
- ,outfile,strerror(errno));
- }else{
- // We write the header
- ret = 0;
- BDICT_HEADER hd;
- hd.magic = BDICT_MAGIC;
- hd.version = BDICT_VERSION;
- hd.nbsys = nbsys;
- fwrite (&hd,sizeof(hd),1,fout);
- long offset_msg = sizeof(hd);
-
- // Then the header of each system
-
- int i;
- for (i=0; i<nbsys; i++){
- TR_STRINGS_COMP *tr = trs + i;
- BDICT_SYSTEM sys;
- memset (&sys,0,sizeof(sys));
- strcpy (sys.name,sysnames[i]);
- sys.version = tr->ref.getversion();
- sys.nbmsg = tr->ref.getnb();
- fwrite (&sys,sizeof(sys),1,fout);
- offset_msg += sizeof (BDICT_SYSTEM) + sys.nbmsg*sizeof(long);
- }
-
- // Then the lookup table for each system
- // offset_msg now point to the beginning of the raw messages
- // area
- for (i=0; i<nbsys; i++){
- TR_STRINGS_COMP *tr = trs + i;
- int n = tr->ref.getnb();
- TR_STRINGS *trans = &tr->trans;
- for (int m=0; m<n; m++){
- TR_STRING *t = tr->ref.getitem(m);
- fwrite (&offset_msg,sizeof(offset_msg),1,fout);
- const char *msg = msgcomp_getmsg (t,trans,lang
- ,sysnames[i]);
- if (msg == NULL) msg = MISSING_MESSAGE;
- char buf[10000];
- str_compile (msg,buf);
- offset_msg += strlen (buf)+1;
- }
- }
- for (i=0; i<nbsys; i++){
- TR_STRINGS_COMP *tr = trs + i;
- int n = tr->ref.getnb();
- TR_STRINGS *trans = &tr->trans;
- for (int m=0; m<n; m++){
- TR_STRING *t = tr->ref.getitem(m);
- const char *msg = msgcomp_getmsg (t,trans,lang,NULL);
- if (msg == NULL) msg = MISSING_MESSAGE;
- char buf[10000];
- str_compile (msg,buf);
- int len = strlen (buf)+1;
- fwrite (buf,len,1,fout);
- }
- }
- fclose (fout);
- }
- return ret;
- }
-
-
- int main (int _argc, char *_argv[])
- {
- char *argv[200];
- int argc = anlparm (_argc,_argv,argv);
- int ret = -1;
- if (argc < 4){
- fprintf (stderr,"msgcomp -ppath [-ppath] resfile lang_select dictionary ...\n");
- }else{
- char **tbsys = (char**)malloc(argc*sizeof(char*));
- ret = 0;
- int a;
- const char *paths[2];
- paths[0] = paths[1] = "";
- int nbpath = 0;
- for (a=1; a<argc; a++){
- char *arg = argv[a];
- if (arg[0] == '-'){
- if (arg[1] == 'p'){
- if (nbpath == 2){
- fprintf (stderr,"Option -p may be used only twice\n");
- }else if (arg[2] == '\0'){
- a++;
- paths[nbpath++] = argv[a];
- }else{
- paths[nbpath++] = arg+2;
- }
- }else{
- fprintf (stderr,"Invalid option %s\n",arg);
- }
- }else{
- break;
- }
- }
- const char *res = argv[a++];
- char *lang = argv[a++];
-
- TR_STRINGS_COMP *trs = new TR_STRINGS_COMP[argc];
- for (int i=a; i<argc; i++){
- char *syspath = argv[i];
- TR_STRINGS_COMP *tr = trs + i - a;
- char path[MAXIMUM_PATH];
- sprintf (path,"%s%s.dic",paths[0],syspath);
- printf ("Processing %s\n",path);
- tr->ref.read (path);
- char *pt = strrchr (syspath,'/');
- if (pt != NULL) syspath = pt+1;
- tbsys[i-a] = strdup(syspath);
- if (tr->ref.getnb()==0){
- fprintf (stderr,"Empty dictionary %s\n"
- ,argv[i]);
- ret = -1;
- }
- if (nbpath == 2){
- sprintf (path,"%s%s.dic",paths[1],argv[i]);
- printf (" %s\n",path);
- tr->trans.read (path);
- }
- }
- if (ret != -1){
- ret = msgcomp_write (res,trs,tbsys,argc-a,lang);
- }else{
- fprintf (stderr
- ,"**** There were some error(s)\n"
- "**** No message produced\n");
- }
- }
- return ret;
- }
-
-